//
//  PublishTextView.swift
//  EyeVisionForPatients
//
//  Created by PMC on 2020/2/14.
//  Copyright © 2020 tao Tao. All rights reserved.
//

import UIKit

@objc protocol PublishTextViewDelegate: NSObjectProtocol {
   @objc optional func textViewShouldBeginEditing(_ textView: UITextView) -> Bool
    
   @objc optional func textViewShouldEndEditing(_ textView: UITextView) -> Bool
   
   @objc optional func textViewDidBeginEditing(_ textView: UITextView)
   
   @objc optional func textViewDidEndEditing(_ textView: UITextView)
   
   
   @objc optional func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
   
   @objc optional func textViewDidChange(_ textView: UITextView)
   
   @objc optional func textViewDidChangeSelection(_ textView: UITextView)
   
   @objc optional func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool
}

class PublishTextView: UITextView {
    weak var tvDelegate: PublishTextViewDelegate?

    /// 占位字符颜色
    var placeholderColor: UIColor = .textLight { didSet { setNeedsLayout() } }
    
    /// 占位字符
    var placeholder: String = "" { didSet { setNeedsLayout() } }
    
    /// 文字最小字数, 默认 0
    var minNumberOfWords: Int = 0 { didSet { setNeedsLayout() } }
    
    /// 文字最大字数, 默认 300
    var maxNumberOfWords: Int = 300 { didSet { setNeedsLayout() } }
    
    var showTextCountView: Bool = true { didSet { setNeedsLayout() } }
    
    var textLayer: CATextLayer!
    
    var countTextLayer: CATextLayer!
    
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        delegate = self
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        delegate = self
    }
}

extension PublishTextView {
    override func layoutSubviews() {
        super.layoutSubviews()
        
        if textLayer == nil {
            textLayer = CATextLayer()
            textLayer.contentsScale = UIScreen.main.scale
            textLayer.alignmentMode = .left
            textLayer.backgroundColor = UIColor.clear.cgColor
            textLayer.foregroundColor = placeholderColor.cgColor
            textLayer.font = font
            textLayer.fontSize = font!.pointSize
            textLayer.string = placeholder
            textLayer.contentsScale = 2.0
            textLayer.isWrapped = true
            textLayer.frame = CGRect(origin: CGPoint(x: 5, y: bounds.minY + 8), size: bounds.size)
            
            layer.insertSublayer(textLayer, at: 0)
        }
        
        if showTextCountView {
            if countTextLayer == nil {
                countTextLayer = CATextLayer()
                countTextLayer.contentsScale = UIScreen.main.scale
                countTextLayer.alignmentMode = .right
                countTextLayer.backgroundColor = UIColor.clear.cgColor
                countTextLayer.foregroundColor = placeholderColor.cgColor
                countTextLayer.font = font
                countTextLayer.fontSize = font!.pointSize
                
                let tempLabel = UILabel()
                let tempText = "\(maxNumberOfWords)/\(maxNumberOfWords)"
                tempLabel.text = tempText
                tempLabel.font = font
                tempLabel.sizeToFit()
                
                countTextLayer.frame = tempLabel.frame
                countTextLayer.string = "\(minNumberOfWords)/\(maxNumberOfWords)"
                layer.addSublayer(countTextLayer)
            }
            
            countTextLayer.frame.origin = CGPoint(x: bounds.size.width - countTextLayer.bounds.size.width, y: bounds.size.height - countTextLayer.bounds.size.height + contentOffset.y)
        }
        
        delegate!.textViewDidChange!(self)
    }
}

extension PublishTextView: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        guard showTextCountView else { return }
        
        countTextLayer.string = "\(text.count)/\(maxNumberOfWords)"
        textLayer.isHidden = text.count > 0
        
        if let delegate = tvDelegate, delegate.responds(to: #selector(textViewDidChange(_:)))  {
            delegate.textViewDidChange!(textView)
        }
    }
    
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        var result: Bool = true
        let oldText = textView.text as NSString
        let newText = oldText.replacingCharacters(in: range, with: text)
        
        if let delegate = tvDelegate, delegate.responds(to: #selector(textView(_:shouldChangeTextIn:replacementText:))) {
            result = delegate.textView!(textView, shouldChangeTextIn: range, replacementText: text)
        }
        
        guard showTextCountView == true else { return result }
        
        return newText.count > maxNumberOfWords ? false : result
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        if let delegate = tvDelegate, delegate.responds(to: #selector(textViewDidEndEditing(_:))) {
            delegate.textViewDidEndEditing!(textView)
        }
    }
}
